package gitwork;
import java.util.*;
import java.io.*;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.time.Month;
import java.util.stream.Collectors;
 class Bill {
    private LocalDate date;
    private double amount; 
    private String category;
    private String note;
    boolean isIncome; 

    public Bill(LocalDate date, double amount, String category, String note, boolean isIncome) {
        if (amount <= 0) throw new IllegalArgumentException("Amount must be positive.");
        this.date = date;
        this.amount = amount;
        this.category = category;
        this.note = note;
        this.isIncome = isIncome;
    }

    public LocalDate getDate() {
        return date;
    }

    public double getAmount() {
        return amount;
    }

    public String getCategory() {
        return category;
    }

    public String getNote() {
        return note;
    }

    public boolean isIncome() {
        return isIncome;
    }

    public String toString() {
        return "Date: " + date + ", Amount: " + amount + ", Category: " + category + ", Note: " + note;
    }
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Bill bill = (Bill) o;
        return Double.compare(bill.amount, amount) == 0 &&
                isIncome == bill.isIncome &&
                Objects.equals(date, bill.date) &&
                Objects.equals(category, bill.category) &&
                Objects.equals(note, bill.note);
    }

    public int hashCode() {
        return Objects.hash(date, amount, category, note, isIncome);
    }
}
 class Budget{
	 private Month month;
	 private double limit;
	 private double spent;
	 public Budget(Month monthh,double limit){
		 this.month=month;
		 this.limit=limit;
		 this.spent=0.0;
	 }
	 public void addSpending(double amount){
		 this.spent+=amount;
	 }
	 public  double getRemainingBudget(){
		 return limit-spent;
	 }
 }
class BillService {
	    private List<Bill> bills = new ArrayList<>();
	    private DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");

	    public void addBill(Scanner scanner, boolean isIncome) {
	        System.out.print("Enter the date (yyyy-MM-dd): ");
	        String dateString = scanner.next();
	        LocalDate date = parseDate(dateString);
	        System.out.print("Enter the amount: ");
	        double amount = scanner.nextDouble();
	        scanner.nextLine(); 
	        System.out.print("Enter the category: ");
	        String category = scanner.nextLine();
	        System.out.print("Enter a note (optional): ");
	        String note = scanner.nextLine();

	        Bill bill = new Bill(date, amount, category, note, isIncome);
	        bills.add(bill);
	    }

	    public void showBills(boolean isIncome) {
	        for (Bill bill : bills) {
	            if (bill.isIncome== isIncome) {
	                System.out.println(bill);
	            }
	        }
	    }

	    public List<Bill> getBills() {
	    	return new ArrayList<>(bills);
	    }

	    private LocalDate parseDate(String dateString) {
	        try {
	            return LocalDate.parse(dateString, formatter);
	        } catch (DateTimeParseException e) {
	            System.out.println("Invalid date format. Please use yyyy-MM-dd.");
	            return null;
	        }
	    }
	}
 class BudgetService {
    private Map<Integer, Budget> budgets = new HashMap<>(); // Key is the month number

    public void setBudget(Scanner scanner) {
        System.out.print("Enter the month (1-12): ");
        int monthNumber = scanner.nextInt();
        System.out.print("Enter the budget limit: ");
        double limit = scanner.nextDouble();
        Month month = Month.of(monthNumber);
        budgets.put(monthNumber, new Budget(month, limit));
    }

    public void updateSpending(Bill bill) {
        if (!bill.isIncome) { // ֻ    ֧  
            int monthNumber = bill.getDate().getMonthValue(); //   ȡ · 
            Budget budget = budgets.get(monthNumber);
            if (budget != null) {
                budget.addSpending(bill.getAmount());
            }
        }
    }

    public void showRemainingBudget(int monthNumber) {
        Budget budget = budgets.get(monthNumber);
        if (budget != null) {
            System.out.println("Remaining budget for "  + ": " + budget.getRemainingBudget());
        } else {
            System.out.println("No budget set for that month.");
        }
    }

}
class StaticsService{
	public void monthlySummary(List<Bill>bills){
		Map<Month,Map<Boolean,Double>>monthlySummary=bills.stream().collect(Collectors.groupingBy(bill->bill.getDate().getMonth(),Collectors.groupingBy(Bill::isIncome,Collectors.summingDouble(Bill::getAmount) )));
		for(Map.Entry<Month,Map<Boolean,Double>>entry:monthlySummary.entrySet()){
			Month month=entry.getKey();
			double totalIncome=entry.getValue().getOrDefault(true, 0.0);
			double totalExpense=entry.getValue().getOrDefault(false, 0.0);
			System.out.println("Month:"+month);
			System.out.println("Total Income:"+totalIncome);
			System.out.println("Total Expense"+totalExpense);
			System.out.println("Net Balance:"+(totalIncome-totalExpense));
			System.out.println("-------------------------");
		}
	}
}
public class git {
	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
        BillService billService = new BillService();
        BudgetService budgetService = new BudgetService();
        StaticsService statisticsService=new StaticsService();
        int choice = 0;
        
        while (choice != 9) { 
            System.out.println("1.   ¼    ");
            System.out.println("2.   ¼֧  ");
            System.out.println("3.  ˵ չʾ");
            System.out.println("4.  ˵   ѯ");
            System.out.println("5.     Ԥ  ");
            System.out.println("6.   ʾ ¶ ͳ  ");
            System.out.println("7.   ʾʣ  Ԥ  ");
            System.out.println("8.  ˳ ");
            
            System.out.print("  ѡ  : ");
            choice = scanner.nextInt();
            switch (choice) {
                case 1:
                    billService.addBill(scanner, true);
                    break;
                case 2:
                    billService.addBill(scanner, false);
                    budgetService.updateSpending(billService.getBills().get(billService.getBills().size() - 1));
                    break;
                case 3:
                    System.out.println("    :");
                    billService.showBills(true);
                    System.out.println("֧  :");
                    billService.showBills(false);
                    break;
                case 4:
                    billService.showBills(true);
                    break;
                case 5:
                    budgetService.setBudget(scanner);
                    break;
                case 6:
                    List<Bill>allBills=billService.getBills();
                    if(allBills.isEmpty()){
                    	System.out.println("û   ˵   ¼    ͳ  ");
                    }else{
                    	statisticsService.monthlySummary(allBills);
                    }
                    break;
                case 7:
                    System.out.print("       ·  (1-12): ");
                    int month = scanner.nextInt();
                    budgetService.showRemainingBudget(month);
                    break;
                case 8:
                    System.out.println("ллʹ ã ");
                    break;
                default:
                    System.out.println("  Ч  ѡ       ԡ ");
            }
        }
        scanner.close();
	}
}
//添加功能：预算管理、月度统计